package com.lemon.boot.common.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.lemon.boot.common.entity.FileInfo;
import com.lemon.boot.common.enums.OssBucketEnum;
import com.lemon.boot.common.exception.CustomException;
import com.lemon.boot.common.properties.FileConfigProperties;
import com.lemon.boot.common.properties.OssConfigProperties;
import com.lemon.boot.common.service.FileService;
import com.lemon.boot.common.utils.LocalDateUtil;
import com.lemon.boot.common.utils.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;

/**
 * @author 李猛
 * @datetime 2024/7/26 12:12
 * @description TODO
 */
@Slf4j
@Service
public class FileServiceImpl implements FileService {
    @Resource
    private FileConfigProperties fileConfigProperties;
    @Resource
    private OssConfigProperties ossConfigProperties;

    @Override
    public FileInfo localUpload(MultipartFile file) {
        log.info("文件上传-本地");
        //1.获取当前日期的字符串
        String date = LocalDate.now().format(LocalDateUtil.DATE_FORMATTER_10);

        //2.获取文件名
        String originName = file.getOriginalFilename();
        if (!StringUtils.hasText(originName)) {
            throw new CustomException("文件异常！");
        }

        //3.截取文件后缀，包括.
        String lastName = originName.substring(originName.lastIndexOf("."));

        //4.生成新的名字
        String newName = RandomUtil.randomString(40) + lastName;

        //5.保存的全路径
        String fullPath = String.format("%s%s/%s", fileConfigProperties.getResourceLocation(), date, newName);

        //6.判断路径是否存在
        File files = new File(fullPath);
        if (!files.getParentFile().exists()) {
            boolean isMk = files.getParentFile().mkdirs();
            if (!isMk) {
                throw new CustomException("文件夹创建失败！");
            }
        }

        //7.保存上传文件
        try {
            file.transferTo(files);
        } catch (IOException e) {
            throw new CustomException(e.getMessage());
        }

        //8.后缀
        String pathMatch = fileConfigProperties.getPathMatch().replaceAll("\\*", "");

        //9.生成读取文件的url
        String url = String.format("%s%s%s/%s", RequestUtil.getServerUrl(), pathMatch, date, newName);

        //10.封装返回值
        return new FileInfo().setOriginName(originName).setNewName(newName).setFullPath(fullPath).setUrl(url);
    }

    @Override
    public FileInfo ossUpload(MultipartFile file) {
        return ossUpload(file, OssBucketEnum.DEFAULT);
    }

    @Override
    public FileInfo ossUpload(MultipartFile file, OssBucketEnum ossBucketEnum) {
        log.info("文件上传-OSS");

        //1.原始文件名
        String originName = file.getOriginalFilename();
        if (!StringUtils.hasText(originName)) {
            throw new CustomException("文件异常！");
        }

        //2.获取文件流
        InputStream inputStream;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            throw new CustomException("文件异常！");
        }

        //3.截取文件后缀，包括.
        String lastName = originName.substring(originName.lastIndexOf("."));

        //4.生成新的名字
        String newName = RandomUtil.randomString(40) + lastName;

        //5.全名（去掉前后 /）
        String uploadName = String.format("%s/%s", ossBucketEnum.getFolder().replaceAll("(^/+)|(/+$)", ""), newName);

        //6.上传请求
        PutObjectRequest putObjectRequest = new PutObjectRequest(ossBucketEnum.getBucketName(), uploadName, inputStream);

        //7.上传
        OSS oss = ossConfigProperties.getOss();
        PutObjectResult putObjectResult = oss.putObject(putObjectRequest);
        if (putObjectResult == null) {
            throw new CustomException("上传失败！");
        }

        //8.关闭
        oss.shutdown();

        //9.url
        String url = String.format("https://%s.%s/%s", ossBucketEnum.getBucketName(), ossConfigProperties.getEndpoint(), uploadName);

        return new FileInfo().setOriginName(originName).setNewName(newName).setUrl(url);
    }
}
